package service

import (
	"encoding/json"
	"fmt"
	"log"
	"math"
	"net/http"
	"strconv"
	"time"
	"webapp/config"
	"webapp/model"
	"webapp/utils"
)

var (
	Token map[string]string
)

func loginFailed(w http.ResponseWriter) {
	jstr, _ := json.Marshal(&model.LoginRet{Success: false})
	fmt.Fprintf(w, string(jstr))
}

func VerifyManager(token string) bool {
	username := Token[token]
	log.Println(username, "verify manager  ")
	user, _ := model.GetUserByName(username)
	if user == nil {
		return false
	}
	if user.Role == 1 {
		log.Println("success")
		return true
	}
	log.Println("failed")
	return false
}

func VerifyUser(token string) bool {
	username := Token[token]
	if username == "" {
		return false
	}
	log.Println(username, "verify user")
	return true
}

func LoginService(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(1>>64 - 1)
	form := r.Form

	username := form.Get("username")
	passwdToVarify := form.Get("password")
	timestamp := form.Get("timestamp")
	nowTime := time.Now().Unix()
	timestampInt, err := strconv.ParseInt(timestamp, 10, 64)
	if err != nil {
		log.Println(username, "login failed")
		loginFailed(w)
		return
	}
	if math.Abs(float64(nowTime-timestampInt/1000)) > config.Overtime {
		loginFailed(w)
		log.Println(username, "login overtime")
		return
	}

	userFound, _ := model.GetUserByName(username)

	if userFound == nil {
		loginFailed(w)
		return
	}

	passwd := utils.MdStr(userFound.Password + timestamp)

	if passwd == passwdToVarify {
		token := utils.MdStr(passwd)
		Token[token] = username
		jstr, _ := json.Marshal(&model.LoginRet{Success: true, Token: token, Role: userFound.Role})
		fmt.Fprintf(w, string(jstr))

		log.Println(userFound.Username, "login success")
		return
	}
	log.Println(username, "login failed")
	loginFailed(w)
	return

}

func RegisterService(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(1>>64 - 1)
	form := r.Form

	username := form.Get("username")
	password := form.Get("password")

	user, _ := model.GetUserByName(username)
	if user != nil {
		jstr, _ := json.Marshal(&model.SimpleRet{Success: false})
		fmt.Fprintf(w, string(jstr))
		return
	}
	newUser := &model.User{model.GetUsersNewId(), username, password, 0}
	err := newUser.AddUser()
	if err != nil {
		fmt.Fprintln(w)
	}
	jstr, _ := json.Marshal(&model.SimpleRet{Success: true})
	fmt.Fprintf(w, string(jstr))

}

func LogoutService(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(1>>64 - 1)
	form := r.Form
	username := form.Get("username")
	token := form.Get("token")

	if Token[token] == username {
		jstr, _ := json.Marshal(&model.SimpleRet{Success: true})
		fmt.Fprintf(w, string(jstr))
		delete(Token, username)
		return
	}
	jstr, _ := json.Marshal(&model.SimpleRet{Success: false})
	fmt.Fprintf(w, string(jstr))
}

func GetUserListService(w http.ResponseWriter, r *http.Request) {
	r.ParseMultipartForm(1>>64 - 1)
	form := r.Form
	token := form.Get("token")
	managerVerify := VerifyManager(token)
	if !managerVerify {
		jstr, _ := json.Marshal(&model.GetUserListRet{Success: false})
		fmt.Fprintf(w, string(jstr))
		return
	}
	userList, _ := model.GetUserList()
	jstr, _ := json.Marshal(&model.GetUserListRet{Success: true, UserList: userList})
	fmt.Fprintf(w, string(jstr))

}

func ToggleManagerService(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	form := r.Form
	token := form.Get("token")
	managerVerify := VerifyManager(token)
	if !managerVerify {
		jstr, _ := json.Marshal(&model.SimpleRet{Success: false})
		fmt.Fprintf(w, string(jstr))
		return
	}
	userId := form.Get("userId")
	userIdInt, err := strconv.Atoi(userId)
	if err != nil {
		jstr, _ := json.Marshal(&model.SimpleRet{Success: false})
		fmt.Fprintf(w, string(jstr))
		return
	}
	err = model.ToggleManager(userIdInt)
	if err != nil {
		jstr, _ := json.Marshal(&model.SimpleRet{Success: false})
		fmt.Fprintf(w, string(jstr))
		return
	}
	jstr, _ := json.Marshal(&model.SimpleRet{Success: true})
	fmt.Fprintf(w, string(jstr))

}

func DeleteUserService(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	form := r.Form
	token := form.Get("token")
	managerVerify := VerifyManager(token)
	if !managerVerify {
		jstr, _ := json.Marshal(&model.SuccessAndLogoutRet{Success: false, Logout: true})
		fmt.Fprintf(w, string(jstr))
		return
	}

	userId := form.Get("userId")
	userIdInt, err := strconv.Atoi(userId)
	if err != nil {
		jstr, _ := json.Marshal(&model.SuccessAndLogoutRet{Success: false, Logout: false})
		fmt.Fprintf(w, string(jstr))
		return
	}
	user, err := model.GetUserById(userIdInt)
	if err != nil {
		jstr, _ := json.Marshal(&model.SuccessAndLogoutRet{Success: false, Logout: false})
		fmt.Fprintf(w, string(jstr))
		return
	}
	err = user.DeleteUser()
	if err != nil {
		jstr, _ := json.Marshal(&model.SuccessAndLogoutRet{Success: false, Logout: false})
		fmt.Fprintf(w, string(jstr))
		return
	}
	jstr, _ := json.Marshal(&model.SuccessAndLogoutRet{Success: true, Logout: false})
	fmt.Fprintf(w, string(jstr))

}
